package com.cloudkinto.utils;

import com.cloudkinto.common.common.DateUtils;
import com.cloudkinto.common.utils.MathUtils;
import com.cloudkinto.common.utils.StringsUtil;
import com.cloudkinto.service.orderinput.vo.OderInputDetailRes;
import com.cloudkinto.service.orderinput.vo.OrderInputPackageDetail;
import com.cloudkinto.service.orderinput.vo.OrderInputProductDetail;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Min;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.List;

public class BarCodePdfUtils {
    public static final float defaultFixHeight = 58f;//默认条形码高度

    /**
     * 新版打印条形码 一页一个
     *
     * @param length
     * @param width
     * @param count
     * @param response
     */
    public static void printBarCodePdf(Map<String, String> attributeMap, int length, int width, int count, String storageSku, String name, HttpServletResponse response) {
        if (count <= 0) {
            return;
        }
        float pageHeight = width * (MathUtils.divBig(3, 842, 297).floatValue());
        float pageLength = length * (MathUtils.divBig(3, 595, 210).floatValue());

        //换算尺寸
        Document doc = new Document();
        doc.setPageSize(new Rectangle(pageLength, pageHeight));
        doc.setMargins(4, 4, 4, 4);
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name + ".pdf", "UTF-8"));
            PdfWriter writer = PdfWriter.getInstance(doc, response.getOutputStream());

            doc.open();

            for (int i = 0; i < count; i++) {
                //因为打印的是一张 一个条形码， 不考虑padding 默认 -1
                PdfPTable barTable = getOneTableNew(attributeMap, writer, length, pageLength, pageHeight, storageSku, "other");
                doc.add(barTable);
                doc.newPage();
            }


        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doc.close();
        }
    }


    /**
     * 生成 pdf中的每整个条形码
     *
     * @param attributeMap
     * @param writer
     * @param pageHeight
     * @param storageSku
     * @param type a4 一张一个  other 其他的 一行三个
     * @return
     * @throws Exception
     */
    public static PdfPTable getOneTable(Map<String, String> attributeMap, PdfWriter writer, int length,float pageLength,float pageHeight,String storageSku, String type) throws Exception {
        //字体格式
        BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

        float height = 0f;//总高度
        PdfPTable barTable = new PdfPTable(1);//table 里面分很多个 小table 一个小table 放 1个条形码
        barTable.setWidthPercentage(100);

        //先生成条形码
        Image image = createBar(writer, storageSku, 26, 1, 8);
        PdfPCell imageCell = createPdfPCell(image, Math.min(pageHeight - 20, defaultFixHeight));
//                imageCell.getWidth()
        barTable.addCell(imageCell);
        height += imageCell.getFixedHeight();
        float imageWidth = imageCell.getImage().getWidth();
        float padding = 0f;
        Font font = null;
        float fixedHeight = 0f;
        if ("a4".equals(type)) {
            fixedHeight = 11f;
            font = new Font(bf, 10, Font.NORMAL);
            if (imageWidth < 80.8) {
                padding = -1f;
            }
            else {
                padding = -8f ;
                float width = 80.8f;
                while ((MathUtils.add(width, 8.8f)) <= imageWidth) {
                    width = MathUtils.add(width, 8.8f);

                    if (width < 142.4) {//256.8
                        padding += -3f;
                    }
                    else if (width > 248) {
                        padding += 0f;
                    }
                    else {
                        padding += -1f;
                    }
                }
            }

        }
        else if (100 == length) {
            fixedHeight = 10f;
            font = new Font(bf, 9, Font.NORMAL);
            if (imageWidth < 124.8f) {
                padding = -1f;
            }
            else {
                padding = -8f ;
                float width = 124.8f;
                while ((MathUtils.add(width, 8.8f)) <= imageWidth) {
                    width = MathUtils.add(width, 8.8f);

                    if (width < 177.6) {//256.8
                        padding += -3f;
                    }
                    else if (width > 248) {
                        padding += 0f;
                    }
                    else {
                        padding += -1f;
                    }
                }
            }

        }
        else if (80 == length) {
            //80 * 60
            fixedHeight = 10f;
            font = new Font(bf, 9, Font.NORMAL);
            if (imageWidth < 89.6f) {
                padding = -1f;
            }
            else {
                padding = -8f ;
                float width = 89.6f;
                while ((MathUtils.add(width, 8.8f)) <= imageWidth) {
                    width = MathUtils.add(width, 8.8f);
                    if (width < 160) {//256.8
                        padding += -3f;
                    }
                    else if (width > 248) {
                        padding += 0f;
                    }
                    else {
                        padding += -1f;
                    }
                }
            }
        }
        else if (70 == length) {
            fixedHeight = 9f;
            font = new Font(bf, 8, Font.NORMAL);
            padding = -1f;
        }
        else if (50 == length) {
            fixedHeight = 8f;
            font = new Font(bf, 7, Font.NORMAL);
            padding = -1f;
        }

        else {
            fixedHeight = 5f;
            font = new Font(bf, 4, Font.NORMAL);
            padding = -1f;
        }

        //生成条形码下方的属性
        for (String key : attributeMap.keySet()) {
            String value = attributeMap.get(key).length() > 26 ? StringsUtil.subStringByUnic(attributeMap.get(key), 20) + "..." : attributeMap.get(key);
            Paragraph paragraph = createParagraph(value, font);

            PdfPCell pdfPCell = createPdfPCell(paragraph, PdfPCell.ALIGN_TOP, padding,fixedHeight);//第一个 向上偏移 3
//            PdfPCell pdfPCell = createPdfPCell(paragraph, PdfPCell.ALIGN_TOP, storageSku.length() > 18 ? -8 : (storageSku.length() > 4 ? -4 : -storageSku.length()) );//第一个 向上偏移 3



            if ((height + pdfPCell.getFixedHeight()) > (pageHeight - 20)) {
//                break;
            }
            barTable.addCell(pdfPCell);
            height += pdfPCell.getFixedHeight();
        }
        barTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
        return barTable;
    }



    /**
     * 生成 pdf中的每整个条形码
     *
     * @param attributeMap
     * @param writer
     * @param pageHeight
     * @param storageSku
     * @param type         a4 一张一个  other 其他的 一行三个
     * @return
     * @throws Exception
     */
    public static PdfPTable getOneTableNew(Map<String, String> attributeMap, PdfWriter writer, int length, float pageLength, float pageHeight, String storageSku, String type) throws Exception {
        //字体格式
        BaseFont bf = BaseFont.createFont("Helvetica", "Cp1252", BaseFont.NOT_EMBEDDED);
        BaseFont bfC = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);


        float height = 0f;//总高度
        PdfPTable barTable = new PdfPTable(1);//table 里面分很多个 小table 一个小table 放 1个条形码
        barTable.setWidthPercentage(100);
        float barHeightX = 2f / 3f;
        float padding = -2f;
        float barPadding = 8f;
        float fixedHeight = 0f;
        float fontSize = 4;
        float scalX = 1;
        int paddingScalx = 2;
        if ("a4".equals(type)) {
            fixedHeight = 14f;
            fontSize = 12;
        } else if (100 == length) {
            fixedHeight = 20f;
            fontSize = 18;
            scalX = 1.4f;
            barPadding = 20f;
            paddingScalx = 3;
        } else if (80 == length) {
            //80 * 60
            fixedHeight = 15f;
            fontSize = 14;
            scalX = 1.2f;
            barPadding = 15f;
            paddingScalx = 3;
        } else if (70 == length || 60 == length) {
            fixedHeight = 9f;
            fontSize = 8;
            paddingScalx = 3;
        } else if (50 == length) {
            fixedHeight = 8f;
            fontSize = 7;
        } else {
            fixedHeight = 4f;
        }
        if ("a4".equals(type)) {
            barHeightX = (pageHeight - 56) / 8f - fixedHeight * attributeMap.size();
        } else {
            barHeightX = pageHeight - 8 - fixedHeight * attributeMap.size();
        }
        if (attributeMap.size() <= 3) {
            barHeightX -= 10f;
        }
        //先生成条形码
        Image image = createBar(writer, storageSku, (int) Math.min(60, barHeightX), scalX, barPadding);
        PdfPCell imageCell = createPdfPCell(image, (int) Math.min(60, barHeightX));
        barTable.addCell(imageCell);
        height += imageCell.getFixedHeight();


        //生成条形码下方的属性
        for (String key : attributeMap.keySet()) {
            float addSize = 0f;

            if (attributeMap.size() <= 3 && "1commoditySku".equals(key)) {
                addSize = 10f;
            }
            Font font = new Font(bf, fontSize + addSize, Font.NORMAL);
            if ("3productName".equals(key)) {
                font = new Font(bfC, fontSize + addSize, Font.NORMAL);
            }
            // else  if (attributeMap.size() <= 4 && "1commoditySku".equals(key)) {
            //     addSize = 3f;
            // }
            // else  if (attributeMap.size() <= 5 && "1commoditySku".equals(key)) {
            //     addSize = 2f;
            // }
            String value = attributeMap.get(key).length() > 26 ? StringsUtil.subStringByUnic(attributeMap.get(key), 20) + "..." : attributeMap.get(key);
            Paragraph paragraph = createParagraph(value, font);
            PdfPCell pdfPCell = createPdfPCell(paragraph, PdfPCell.ALIGN_TOP, padding - addSize / paddingScalx, fixedHeight + addSize);//第一个 向上偏移 3
//            PdfPCell pdfPCell = createPdfPCell(paragraph, PdfPCell.ALIGN_TOP, storageSku.length() > 18 ? -8 : (storageSku.length() > 4 ? -4 : -storageSku.length()) );//第一个 向上偏移 3

            if ((height + pdfPCell.getFixedHeight()) > (pageHeight - 20)) {
//                break;
            }
            barTable.addCell(pdfPCell);
            height += pdfPCell.getFixedHeight();
        }
//        barTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
        return barTable;
    }


    /**
     * 打印A4纸张尺寸 一排放三个
     */
    public static void printPdfA4(Map<String, String> attributeMap, int count, String storageSku, String name, HttpServletResponse response) {
        if (count <= 0) {
            return;
        }
        float pageHeight = 297f * (MathUtils.divBig(3, 842, 297).floatValue());
        float pageLength = 210f * (MathUtils.divBig(3, 595, 210).floatValue());

        //换算尺寸
        Document doc = new Document();
        doc.setPageSize(new Rectangle(pageLength, pageHeight));
        doc.setMargins(10, 10, 10, 10);
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name + ".pdf", "UTF-8"));
            PdfWriter writer = PdfWriter.getInstance(doc, response.getOutputStream());

            doc.open();
            PdfPTable table = new PdfPTable(3);//设置 一行 放多少个条形码，A4 3个，其他规格一页一个, 最大的table
            table.setWidthPercentage(100);
            table.getDefaultCell().setBorder(Rectangle.NO_BORDER);

            for (int i = 0; i < count; i++) {
                //a4纸打印 考虑padding 可能挤压图片， paddingTop 根据 图片的宽度决定，当宽度小于80.8默认-1，往后每增加8.8，paddingTop加 -3
                PdfPTable barTable = getOneTableNew(attributeMap, writer, 210, pageLength, pageHeight, storageSku, "a4");
                table.addCell(barTable);
                table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
            }
            while (count % 3 != 0) {
                count++;
                PdfPCell cell1 = new PdfPCell();
//                cell1.setRowspan(8);
                cell1.setBorder(Rectangle.NO_BORDER);
//                cell1.setPadding(22);
                table.addCell(cell1);
            }
            doc.add(table);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doc.close();
        }
    }


    /**
     * 入库单打印 a4
     *
     * @param detailRes
     * @param name
     * @param response
     */
    public static void orderInputPrintA4(Map<String, String> map, OderInputDetailRes detailRes, String name, HttpServletResponse response) {

        float pageHeight = 297f * (MathUtils.divBig(3, 842, 297).floatValue());
        float pageLength = 210f * (MathUtils.divBig(3, 595, 210).floatValue());

        //换算尺寸
        Document doc = new Document();
        doc.setPageSize(new Rectangle(pageLength, pageHeight));
        doc.setMargins(10, 10, 10, 10);
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name + ".pdf", "UTF-8"));
            PdfWriter writer = PdfWriter.getInstance(doc, response.getOutputStream());

            doc.open();
            PdfPTable table = new PdfPTable(3);//设置 一行 放多少个条形码，A4 3个，其他规格一页一个, 最大的table
            table.setWidthPercentage(100);
            table.getDefaultCell().setBorder(Rectangle.NO_BORDER);

            int count = 0;
            for (int i = 0; i < detailRes.getPackageList().size(); i++) {
                OrderInputPackageDetail demandPackageOrder = detailRes.getPackageList().get(i);
                for (OrderInputProductDetail product : demandPackageOrder.getProductList()) {

                    Map<String, String> attributeMap = new HashMap<>();
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("commoditySku"))) {
                        attributeMap.put("commoditySku", product.getCommoditySku());
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("storageSku"))) {
                        attributeMap.put("storageSku", product.getStorageSku());
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("productName"))) {
                        attributeMap.put("productName", product.getCommodityName());
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("fnSku")) && org.apache.commons.lang.StringUtils.isNotBlank(product.getFnSku())) {
                        attributeMap.put("fnSku", product.getFnSku());
                    }

                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("madeInChina"))) {
                        attributeMap.put("madeInChina", "Made IN China");
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("printDate"))) {
                        attributeMap.put("printDate", DateUtils.dateFormatToString(new Date(), "yyyy-MM-dd"));
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("productSpec"))) {
                        attributeMap.put("productSpec", product.getLength() + "cm x" + product.getWidth() + "cm x" + product.getHeight() + "cm");
                    }

                    for (int j = 0; j < product.getCount() * demandPackageOrder.getCount(); j++) {
                        count++;
                        PdfPTable barTable = getOneTableNew(attributeMap, writer, 210, pageLength, pageHeight, product.getStorageSku(), "a4");
                        table.addCell(barTable);
                        table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
                    }
                }
            }
            while (count % 3 != 0) {
                count++;
                PdfPCell cell = new PdfPCell();
                cell.setBorder(Rectangle.NO_BORDER);
                table.addCell(cell);
            }
            doc.add(table);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doc.close();
        }
    }

    public static void orderInputPrint(Map<String, String> map, OderInputDetailRes detailRes, int length, int width, String name, HttpServletResponse response) {

        float pageHeight = width * (MathUtils.divBig(3, 842, 297).floatValue());
        float pageLength = length * (MathUtils.divBig(3, 595, 210).floatValue());

        //换算尺寸
        Document doc = new Document();
        doc.setPageSize(new Rectangle(pageLength, pageHeight));
        doc.setMargins(4, 4, 4, 4);
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name + ".pdf", "UTF-8"));
            PdfWriter writer = PdfWriter.getInstance(doc, response.getOutputStream());
            doc.open();

            for (int i = 0; i < detailRes.getPackageList().size(); i++) {
                OrderInputPackageDetail demandPackageOrder = detailRes.getPackageList().get(i);
                for (OrderInputProductDetail product : demandPackageOrder.getProductList()) {
                    Map<String, String> attributeMap = new HashMap<>();
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("commoditySku"))) {
                        attributeMap.put("1commoditySku", product.getCommoditySku());
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("storageSku"))) {
                        attributeMap.put("2storageSku", product.getStorageSku());
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("productName"))) {
                        attributeMap.put("3productName", StringUtils.isBlank(product.getCommodityName())?product.getProductName():product.getCommodityName());
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("fnSku")) && org.apache.commons.lang.StringUtils.isNotBlank(product.getFnSku())) {
                        attributeMap.put("4fnSku", product.getFnSku());
                    }

                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("madeInChina"))) {
                        attributeMap.put("5madeInChina", "Made IN China");
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(map.get("printDate"))) {
                        attributeMap.put("7printDate", DateUtils.dateFormatToString(new Date(), "yyyy-MM-dd"));
                    }
                    if (StringUtils.isNotBlank(map.get("productSpec"))) {
                        attributeMap.put("6productSpec", product.getLength() + "cm x" + product.getWidth() + "cm x" + product.getHeight() + "cm");
                    }
                    for (int j = 0; j < product.getCount() * demandPackageOrder.getCount(); j++) {
                        //因为打印的是一张 一个条形码， 不考虑padding 默认 -1
                        PdfPTable barTable = getOneTableNew(attributeMap, writer, length, pageLength, pageHeight, product.getStorageSku(), "other");
                        doc.add(barTable);
                        doc.newPage();
                    }
                }
            }

        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            doc.close();
        }
    }


    public static Paragraph createParagraph(String string, Font font) {
        Paragraph paragraph = new Paragraph(string, font);
        paragraph.setAlignment(Paragraph.ALIGN_BOTTOM);
        return paragraph;
    }

    /**
     * 生成属性单元格 如产品sku 名称等
     *
     * @param paragraph
     * @param verticalAlignment   PdfPCell.ALIGN_BOTTOM
     * @param horizontalAlignment 水平的 Element.ALIGN_CENTER(居中)  Element.ALIGN_LEFT
     */
    public static PdfPCell createPdfPCell(Paragraph paragraph, int verticalAlignment, int horizontalAlignment, float paddingTop, float fixedHeight) {
        PdfPCell cell = new PdfPCell(paragraph);
        cell.setFixedHeight(fixedHeight);//fixedHeight 貌似 和padding top 相冲突
//        cell.setPadding(0);
        cell.setVerticalAlignment(verticalAlignment);
        cell.setHorizontalAlignment(horizontalAlignment);
        cell.setBorder(Rectangle.NO_BORDER);
        cell.setPaddingLeft(2);
        cell.setPaddingRight(2);
        cell.setPaddingTop(paddingTop);
//        if (paddingTop != 0) {
//            cell.setPaddingTop(paddingTop);
//        }
//        else {
//            cell.setPaddingTop(-1);
//        }
        return cell;
    }


    /**
     * 生成属性单元格 如产品sku 名称等 居中展示
     *
     * @param paragraph
     * @param verticalAlignment PdfPCell.ALIGN_BOTTOM
     */
    public static PdfPCell createPdfPCell(Paragraph paragraph, int verticalAlignment, float paddingTop, float fixedHeight) {
        return createPdfPCell(paragraph, verticalAlignment, Element.ALIGN_CENTER, paddingTop, fixedHeight);
    }

    /**
     * 生成属性单元格 条形码
     *
     * @param image
     * @param fixedHeight 条形码高度
     * @return
     */
    public static PdfPCell createPdfPCell(Image image, int horizontalAlignment, float fixedHeight) {
        PdfPCell cell = new PdfPCell();
//        cell.setRowspan(8);
        cell.setBorder(Rectangle.NO_BORDER);
        cell.setHorizontalAlignment(horizontalAlignment);//水平的
        cell.setVerticalAlignment(PdfPCell.ALIGN_TOP);
        cell.setFixedHeight(fixedHeight);
        cell.setPaddingLeft(2);
        cell.setPaddingRight(2);
        cell.setImage(image);
        return cell;
    }


    /**
     * 生成属性单元格 条形码（居中）
     *
     * @param image
     * @return
     */
    public static PdfPCell createPdfPCell(Image image) {
        return createPdfPCell(image, Element.ALIGN_CENTER, defaultFixHeight);
    }

    /**
     * 生成属性单元格 条形码（居中）
     *
     * @param image
     * @param fixHeight 条形码高度
     * @return
     */
    public static PdfPCell createPdfPCell(Image image, float fixHeight) {
        return createPdfPCell(image, Element.ALIGN_CENTER, fixHeight);
    }


    /**
     * 条形码
     *
     * @param writer
     * @param code      会默认显示在条形码的下方
     * @param barHeight 默认给 26
     * @param scalX     默认给 8
     * @param size      默认给 8
     * @return
     */
    public static Image createBar(PdfWriter writer, String code, int barHeight, float scalX, float size) {
        PdfContentByte cb = writer.getDirectContent();
        Barcode128 barcode128 = new Barcode128();
        barcode128.setCode(code);
        barcode128.setFont(null);//将code 隐藏
        barcode128.setCodeType(Barcode128.CODE128);
        barcode128.setBarHeight(barHeight);
        barcode128.setX(scalX);
        Image image = barcode128.createImageWithBarcode(cb, null, null);
        image.setAlignment(Image.MIDDLE);
        image.setPaddingTop(size);
        return image;
    }
}
